package com.example.order.service.impl;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.example.handler.MyBlockHandlerClass;
import com.example.handler.MyFallbackClass;
import com.example.order.service.SentinelService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * @Author 刘武贵
 * @Date 2024-03-03 21:27
 * @Description 功能描述：测试Sentinel实现类（演示链路流控模式）
 */
@Service
@Slf4j
public class SentinelServiceImpl implements SentinelService {

    /**
     * 测试方法（测试Sentinel的链路流控模式）
     * 该方法用于发送消息，没有参数，也没有返回值。
     */
    @Override
    @SentinelResource("sendMessage")
    public void sendMessage() {
        System.out.println("测试Sentinel的链路流控模式");
    }

    /**
     * 计数器变量，用于记录某些操作的次数或状态。
     */
    private int count = 0;

    /**
     * 发送消息并返回消息内容的方法（演示@SentinelResource注解）
     * 覆盖原有的sendMessage2方法，通过Sentinel框架进行资源控制，提供异常处理和回退机制。
     *
     * @return 返回字符串"sendMessage2"，表示消息发送成功。
     * @throws RuntimeException 当执行次数为4的倍数时，抛出运行时异常，模拟25%的异常率。
     */
    @Override
    /**
     * 使用Sentinel资源注解定义的发送消息方法。
     * 该方法围绕“sendMessage2”这个资源进行了流量控制、异常处理等配置。
     *
     * @SentinelResource注解配置说明：
     *      value - 资源名，即当前方法名。
     *      blockHandlerClass - 流控、降级等场景下的处理类。
     *      blockHandler - 流控、降级等场景下的处理方法名。
     *      fallbackClass - 异常场景下的回退类。
     *      fallback - 异常场景下的回退方法名。
     */
    @SentinelResource(
            value = "sendMessage2",
            blockHandlerClass = MyBlockHandlerClass.class,
            blockHandler = "blockHandler",
            fallbackClass = MyFallbackClass.class,
            fallback = "fallback")
    public String sendMessage2() {
        count ++;
        System.out.println(count);
        // 模拟25%的异常率，当计数为4的倍数时抛出异常
        if (count % 4 == 0){
            throw new RuntimeException("25%的异常率");
        }
        return "sendMessage2";
    }

    /**
     * 处理限流异常的逻辑。
     * 当系统发生限流异常时，记录错误日志，并返回相应的提示信息。
     *
     * @param e 限流异常对象，用于记录具体的限流信息。
     * @return 返回一个表示限流的字符串信息。
     */
    public String blockHandler(BlockException e){
        // 记录限流异常日志
        log.error("限流了:{}", e);
        return "限流了";
    }

    /**
     * 处理通用异常的逻辑。
     * 当系统发生任何未被捕获的异常时，记录错误日志，并返回相应的提示信息。
     *
     * @param e 异常对象，用于记录具体的异常信息。
     * @return 返回一个表示异常的字符串信息。
     */
    public String fallback(Throwable e){
        log.error("异常了:{}", e); // 记录异常日志
        return "异常了";
    }
}
